// 云函数入口文件
const cloud = require('wx-server-sdk')
const crypto = require('crypto')
const request = require('request-promise')

cloud.init({
  env: cloud.DYNAMIC_CURRENT_ENV
})

const db = cloud.database()
const _ = db.command
const ordersCollection = db.collection('orders')

// 支付宝支付配置
const ALIPAY_CONFIG = {
  appId: 'YOUR_ALIPAY_APP_ID', // 替换为实际的支付宝应用ID
  privateKey: 'YOUR_PRIVATE_KEY', // 替换为实际的私钥
  alipayPublicKey: 'ALIPAY_PUBLIC_KEY', // 替换为实际的支付宝公钥
  gateway: 'https://openapi.alipay.com/gateway.do', // 正式环境网关
  // gateway: 'https://openapi.alipaydev.com/gateway.do', // 沙箱环境网关
  charset: 'utf-8',
  version: '1.0',
  signType: 'RSA2',
  format: 'JSON'
}

// 云函数入口函数
exports.main = async (event, context) => {
  const wxContext = cloud.getWXContext()
  
  // 获取用户ID，优先使用openid，如果没有则使用guestId
  const userId = wxContext.OPENID || event.userId
  
  if (!userId) {
    return {
      success: false,
      errMsg: '用户ID不存在'
    }
  }
  
  // 根据操作类型执行不同的逻辑
  switch (event.action) {
    case 'createPayment':
      return await createAlipayPayment(event, userId)
    case 'queryPayment':
      return await queryAlipayPayment(event)
    case 'notifyPayment':
      return await handleAlipayNotify(event)
    default:
      return {
        success: false,
        errMsg: '未知的操作类型'
      }
  }
}

// 创建支付宝支付订单
async function createAlipayPayment(event, userId) {
  try {
    // 检查订单ID
    if (!event.orderId) {
      return {
        success: false,
        errMsg: '订单ID不能为空'
      }
    }
    
    // 查询订单
    const order = await ordersCollection.doc(event.orderId).get()
    
    // 检查订单是否存在
    if (!order || !order.data) {
      return {
        success: false,
        errMsg: '订单不存在'
      }
    }
    
    // 检查订单是否属于当前用户
    if (order.data.userId !== userId) {
      return {
        success: false,
        errMsg: '无权限操作该订单'
      }
    }
    
    // 检查订单状态是否为待支付
    if (order.data.status !== 'pending') {
      return {
        success: false,
        errMsg: '订单状态不允许支付'
      }
    }
    
    // 构建支付宝支付参数
    const bizContent = {
      out_trade_no: order.data._id, // 商户订单号
      total_amount: order.data.totalPayable, // 订单总金额
      subject: '甜蜜时光订单', // 订单标题
      body: `订单包含${order.data.items.length}件商品`, // 订单描述
      product_code: 'QUICK_MSECURITY_PAY', // 销售产品码，固定值
      timeout_express: '30m' // 超时时间
    }
    
    // 构建支付宝请求参数
    const params = {
      app_id: ALIPAY_CONFIG.appId,
      method: 'alipay.trade.app.pay', // APP支付接口
      charset: ALIPAY_CONFIG.charset,
      sign_type: ALIPAY_CONFIG.signType,
      timestamp: new Date().toISOString().replace(/T/, ' ').replace(/\..+/, ''),
      version: ALIPAY_CONFIG.version,
      notify_url: 'https://your-domain.com/alipay-notify', // 支付宝服务器主动通知商户服务器里指定的页面http/https路径
      biz_content: JSON.stringify(bizContent)
    }
    
    // 生成签名
    const signContent = Object.keys(params)
      .sort()
      .map(key => `${key}=${params[key]}`)
      .join('&')
    
    const sign = crypto.createSign('RSA-SHA256')
    sign.update(signContent)
    params.sign = sign.sign(ALIPAY_CONFIG.privateKey, 'base64')
    
    // 更新订单状态为支付中
    await ordersCollection.doc(event.orderId).update({
      data: {
        paymentType: 'alipay',
        paymentStatus: 'processing',
        updateTime: db.serverDate()
      }
    })
    
    return {
      success: true,
      data: {
        orderString: Object.keys(params)
          .map(key => `${key}=${encodeURIComponent(params[key])}`)
          .join('&')
      }
    }
  } catch (err) {
    console.error('创建支付宝支付订单失败:', err)
    return {
      success: false,
      errMsg: '创建支付宝支付订单失败',
      error: err
    }
  }
}

// 查询支付宝支付订单状态
async function queryAlipayPayment(event) {
  try {
    // 检查订单ID
    if (!event.orderId) {
      return {
        success: false,
        errMsg: '订单ID不能为空'
      }
    }
    
    // 构建支付宝查询参数
    const bizContent = {
      out_trade_no: event.orderId // 商户订单号
    }
    
    // 构建支付宝请求参数
    const params = {
      app_id: ALIPAY_CONFIG.appId,
      method: 'alipay.trade.query', // 订单查询接口
      charset: ALIPAY_CONFIG.charset,
      sign_type: ALIPAY_CONFIG.signType,
      timestamp: new Date().toISOString().replace(/T/, ' ').replace(/\..+/, ''),
      version: ALIPAY_CONFIG.version,
      biz_content: JSON.stringify(bizContent)
    }
    
    // 生成签名
    const signContent = Object.keys(params)
      .sort()
      .map(key => `${key}=${params[key]}`)
      .join('&')
    
    const sign = crypto.createSign('RSA-SHA256')
    sign.update(signContent)
    params.sign = sign.sign(ALIPAY_CONFIG.privateKey, 'base64')
    
    // 发送请求到支付宝
    const result = await request({
      method: 'GET',
      url: ALIPAY_CONFIG.gateway,
      qs: params,
      json: true
    })
    
    const responseKey = 'alipay_trade_query_response'
    if (result[responseKey].code === '10000') {
      // 支付成功
      if (result[responseKey].trade_status === 'TRADE_SUCCESS' || 
          result[responseKey].trade_status === 'TRADE_FINISHED') {
        // 更新订单状态
        await ordersCollection.doc(event.orderId).update({
          data: {
            status: 'undelivered',
            paymentStatus: 'paid',
            payTime: db.serverDate(),
            tradeNo: result[responseKey].trade_no, // 支付宝交易号
            updateTime: db.serverDate()
          }
        })
        
        return {
          success: true,
          data: {
            paid: true,
            tradeNo: result[responseKey].trade_no
          }
        }
      }
      
      return {
        success: true,
        data: {
          paid: false,
          tradeStatus: result[responseKey].trade_status
        }
      }
    }
    
    return {
      success: false,
      errMsg: result[responseKey].sub_msg || '查询支付状态失败'
    }
  } catch (err) {
    console.error('查询支付宝支付状态失败:', err)
    return {
      success: false,
      errMsg: '查询支付宝支付状态失败',
      error: err
    }
  }
}

// 处理支付宝支付回调通知
async function handleAlipayNotify(event) {
  try {
    const notifyData = event.notifyData
    
    // 验证签名
    const signContent = Object.keys(notifyData)
      .filter(key => key !== 'sign' && key !== 'sign_type')
      .sort()
      .map(key => `${key}=${notifyData[key]}`)
      .join('&')
    
    const verify = crypto.createVerify('RSA-SHA256')
    verify.update(signContent)
    const signValid = verify.verify(
      ALIPAY_CONFIG.alipayPublicKey,
      notifyData.sign,
      'base64'
    )
    
    if (!signValid) {
      return {
        success: false,
        errMsg: '签名验证失败'
      }
    }
    
    // 验证通知中的app_id是否为该商户本身
    if (notifyData.app_id !== ALIPAY_CONFIG.appId) {
      return {
        success: false,
        errMsg: 'app_id校验失败'
      }
    }
    
    // 查询订单
    const order = await ordersCollection.where({
      _id: notifyData.out_trade_no
    }).get()
    
    if (!order || !order.data || order.data.length === 0) {
      return {
        success: false,
        errMsg: '订单不存在'
      }
    }
    
    // 判断通知中的total_amount是否与订单中的金额一致
    if (parseFloat(notifyData.total_amount) !== parseFloat(order.data[0].totalPayable)) {
      return {
        success: false,
        errMsg: '订单金额不匹配'
      }
    }
    
    // 判断交易状态
    if (notifyData.trade_status === 'TRADE_SUCCESS' || 
        notifyData.trade_status === 'TRADE_FINISHED') {
      // 更新订单状态
      await ordersCollection.doc(notifyData.out_trade_no).update({
        data: {
          status: 'undelivered',
          paymentStatus: 'paid',
          payTime: db.serverDate(),
          tradeNo: notifyData.trade_no, // 支付宝交易号
          updateTime: db.serverDate()
        }
      })
      
      return {
        success: true,
        return_msg: 'success' // 返回给支付宝的消息
      }
    }
    
    return {
      success: true,
      return_msg: 'success' // 返回给支付宝的消息
    }
  } catch (err) {
    console.error('处理支付宝回调通知失败:', err)
    return {
      success: false,
      errMsg: '处理支付宝回调通知失败',
      error: err
    }
  }
}